import pygame
import os
import enum
from network_client import NetworkClient

class Piece(enum.Enum):
    EMPTY = 0
    BLACK = 1
    WHITE = 2

class OnlineGameScreen:
    def __init__(self, game):
        self.game = game
        self.screen = game.screen
        self.width = game.width
        self.height = game.height
        self.username = game.username
        
        # 网络客户端
        self.network = NetworkClient()
        self.setup_network_callbacks()
        
        # 确保之前没有活跃连接
        try:
            self.network.disconnect()
        except:
            pass
            
        # 游戏状态初始化
        self.role = None  # "black" 或 "white"
        self.opponent_name = None
        self.is_my_turn = False
        self.game_over = False  # 确保初始值为False
        self.winner = None
        self.status_message = "正在连接服务器..."
        self.waiting_for_opponent = True  # 等待对手标志
        self.waiting_animation_frame = 0  # 等待动画帧
        self.last_animation_update = pygame.time.get_ticks()  # 上次动画更新时间
        self.connected = False  # 连接状态标志
        self.show_game_over_dialog = True  # 游戏结束时是否显示对话框
        self.show_undo_request_dialog = False  # 是否显示悔棋请求对话框
        self.show_rematch_request_dialog = False  # 是否显示再来一局请求对话框
        self.opponent_disconnected = False  # 对手是否断开连接导致游戏结束
        
        # 延迟一小段时间确保上一个连接完全关闭
        pygame.time.delay(100)
        
        # 尝试连接服务器
        self.connect_to_server()
        
        # 表情相关
        self.emoji_images = {}  # 存储表情图片
        self.show_emoji_panel = False  # 是否显示表情面板
        self.emoji_panel_rect = pygame.Rect(0, 0, 300, 100)  # 表情面板区域
        self.emoji_button_rect = pygame.Rect(0, 0, 40, 40)  # 表情按钮区域
        
        # 加载额外的图片素材
        self.victory_img = None
        self.lose_img = None
        self.wait_img = None
        try:
            victory_path = os.path.join("img", "victory.png")
            lose_path = os.path.join("img", "lose.png")
            wait_path = os.path.join("img", "wait.png")
            
            if os.path.exists(victory_path):
                self.victory_img = pygame.image.load(victory_path)
                # 调整大小为合适的尺寸
                self.victory_img = pygame.transform.scale(self.victory_img, (200, 200))
            
            if os.path.exists(lose_path):
                self.lose_img = pygame.image.load(lose_path)
                # 调整大小为合适的尺寸
                self.lose_img = pygame.transform.scale(self.lose_img, (200, 200))
                
            if os.path.exists(wait_path):
                self.wait_img = pygame.image.load(wait_path)
                # 调整大小为合适的尺寸
                self.wait_img = pygame.transform.scale(self.wait_img, (200, 200))
                
                            # 加载表情图片 - 严格统一大小
                emoji_size = 28  # 统一表情大小，与渲染时保持一致
                for i in range(1, 10):
                    emoji_path = os.path.join("img", f"{i}.webp")
                    if os.path.exists(emoji_path):
                        try:
                            emoji_img = pygame.image.load(emoji_path)
                            # 调整表情大小为严格统一的尺寸
                            emoji_img = pygame.transform.scale(emoji_img, (emoji_size, emoji_size))
                            self.emoji_images[str(i)] = emoji_img
                        except Exception as e:
                            print(f"加载表情图片 {i} 出错: {e}")
        except Exception as e:
            print(f"加载图片素材出错: {e}")
        
        # 颜色定义
        self.white = (255, 255, 255)
        self.black = (0, 0, 0)
        self.gray = (230, 230, 230)
        self.light_gray = (240, 240, 240)
        self.apple_blue = (0, 122, 255)
        self.apple_light_blue = (88, 172, 255)
        self.board_color = (240, 217, 181)
        
        # 字体
        self.font_path = 'C:\\Windows\\Fonts\\simsun.ttc'
        pygame.font.init()
        try:
            self.title_font = pygame.font.Font(self.font_path, 36)
            self.info_font = pygame.font.Font(self.font_path, 24)
            self.chat_font = pygame.font.Font(self.font_path, 18)
            self.timer_font = pygame.font.Font(self.font_path, 28)
        except:
            self.title_font = pygame.font.SysFont("simsun", 36)
            self.info_font = pygame.font.SysFont("simsun", 24)
            self.chat_font = pygame.font.SysFont("simsun", 18)
            self.timer_font = pygame.font.SysFont("simsun", 28)
        
        # 棋盘设置
        self.board_size = 15
        self.cell_size = 48
        self.board_margin = 100
        
        # 计算棋盘位置
        self.board_width = self.cell_size * (self.board_size - 1)
        self.board_x = (self.width - self.board_width - 300) // 2  # 给聊天区域留出空间
        self.board_y = (self.height - self.board_width) // 2
        
        # 创建棋盘区域的矩形
        self.board_rect = pygame.Rect(
            self.board_x - self.cell_size // 2,
            self.board_y - self.cell_size // 2,
            self.board_width + self.cell_size,
            self.board_width + self.cell_size
        )
        
        # 加载棋子图片
        self.black_piece = None
        self.white_piece = None
        try:
            black_path = os.path.join("img", "black.png")
            white_path = os.path.join("img", "white.png")
            if os.path.exists(black_path) and os.path.exists(white_path):
                self.black_piece = pygame.image.load(black_path)
                self.white_piece = pygame.image.load(white_path)
                piece_size = int(self.cell_size * 0.9)
                self.black_piece = pygame.transform.scale(self.black_piece, (piece_size, piece_size))
                self.white_piece = pygame.transform.scale(self.white_piece, (piece_size, piece_size))
        except:
            pass
        
        # 加载音效
        self.down_sound = None
        self.win_sound = None
        self.lose_sound = None
        try:
            down_path = os.path.join("sound", "down.mp3")
            win_path = os.path.join("sound", "victory.mp3")
            lose_path = os.path.join("sound", "lose.mp3")
            
            if os.path.exists(down_path):
                self.down_sound = pygame.mixer.Sound(down_path)
            if os.path.exists(win_path):
                self.win_sound = pygame.mixer.Sound(win_path)
            if os.path.exists(lose_path):
                self.lose_sound = pygame.mixer.Sound(lose_path)
        except:
            pass
        
        # 游戏状态
        self.board = [[Piece.EMPTY for _ in range(self.board_size)] for _ in range(self.board_size)]
        self.current_player = Piece.BLACK
        
        # 聊天相关
        self.chat_messages = []
        self.chat_input = ""
        self.chat_active = False
        self.chat_rect = pygame.Rect(
            self.board_x + self.board_width + 40,
            self.board_y,
            250,
            self.board_width
        )
        self.chat_input_rect = pygame.Rect(
            self.chat_rect.x,
            self.chat_rect.y + self.chat_rect.height - 40,
            self.chat_rect.width - 40,  # 减少宽度，为表情按钮留出空间
            40
        )
        self.chat_history_rect = pygame.Rect(
            self.chat_rect.x,
            self.chat_rect.y,
            self.chat_rect.width,
            self.chat_rect.height - 50
        )
        self.send_button_rect = pygame.Rect(
            self.chat_input_rect.x + self.chat_input_rect.width - 60,
            self.chat_input_rect.y,
            60,
            40
        )
        # 表情按钮
        self.emoji_button_rect = pygame.Rect(
            self.chat_rect.x + self.chat_rect.width - 40,
            self.chat_input_rect.y,
            40,
            40
        )
        # 表情面板 - 调整大小以确保表情不会超出范围
        self.emoji_panel_rect = pygame.Rect(
            self.chat_rect.x,
            self.chat_input_rect.y - 120,  # 增加高度
            self.chat_rect.width,
            120  # 增加高度
        )
        
        # 返回菜单按钮
        self.back_button_rect = pygame.Rect(self.width - 160, 20, 140, 50)
        self.back_button_text = "返回菜单"
        
        # 投降按钮
        self.surrender_button_rect = pygame.Rect(self.width - 160, 80, 140, 50)
        self.surrender_button_text = "投降"
        
        # 悔棋按钮
        self.undo_button_rect = pygame.Rect(self.width - 160, 140, 140, 50)
        self.undo_button_text = "请求悔棋"
        
        # 再来一局
        self.rematch_button_rect = pygame.Rect(self.width - 160, 200, 140, 50)
        self.rematch_button_text = "再来一局"
        self.rematch_button_color = self.apple_light_blue

        # 悔棋相关
        self.move_history = []  # 存储落子历史 [(x, y, piece), ...]
        self.undo_requested = False  # 是否已请求悔棋
        self.undo_allowed = False  # 对方是否同意悔棋
        self.pending_undo_request = False  # 是否有待处理的悔棋请求
        self.undo_requester = None  # 请求悔棋的玩家
        self.last_undo_time = 0  # 上次请求悔棋的时间
        
        # 新增：记录每个玩家的悔棋次数
        self.black_undo_count = 0  # 黑棋悔棋次数
        self.white_undo_count = 0  # 白棋悔棋次数
        self.max_undo_per_turn = 1  # 每回合最大悔棋次数
        
        # 悔棋回应按钮
        self.agree_button_rect = pygame.Rect(self.width - 160, 140, 140, 50)
        self.disagree_button_rect = pygame.Rect(self.width - 160, 200, 140, 50)
        self.agree_button_text = "同意悔棋"
        self.disagree_button_text = "拒绝悔棋"
        
        # 计时器相关
        self.turn_time_limit = 30  # 每回合30秒
        self.black_time_left = self.turn_time_limit
        self.white_time_left = self.turn_time_limit
        self.last_time_update = pygame.time.get_ticks()
        
        # 再来一局响应按钮（当收到对方再来一局请求时显示）
        self.accept_rematch_rect = pygame.Rect(self.width - 160, 200, 140, 50)
        self.accept_rematch_text = "同意再来一局"
        
        self.reject_rematch_rect = pygame.Rect(self.width - 160, 260, 140, 50)
        self.reject_rematch_text = "拒绝再来一局"
    
    def connect_to_server(self):
        """连接到服务器"""
        # 确保先断开之前的连接
        try:
            self.network.disconnect()
        except:
            pass
        # 重新连接 - 必须传递用户名
        try:
            self.network.connect(self.username)
        except Exception as e:
            print(f"连接服务器失败: {e}")
        
        # 游戏结束相关
        self.show_game_over_dialog = False  # 是否显示游戏结束对话框
        self.rematch_requested = False  # 是否已请求重新比赛
        self.opponent_rematch_requested = False  # 对方是否请求重新比赛
        self.ranking_updated = False  # 是否已更新排行榜
    
    def setup_network_callbacks(self):
        """设置网络回调函数"""
        self.network.set_callback("on_connect", self.on_connect)
        self.network.set_callback("on_disconnect", self.on_disconnect)
        self.network.set_callback("on_waiting", self.on_waiting)
        self.network.set_callback("on_match_found", self.on_match_found)
        self.network.set_callback("on_move", self.on_move)
        self.network.set_callback("on_chat", self.on_chat)
        self.network.set_callback("on_game_over", self.on_game_over)
        self.network.set_callback("on_error", self.on_error)
        self.network.set_callback("on_undo_request", self.on_undo_request)
        self.network.set_callback("on_undo_response", self.on_undo_response)
        self.network.set_callback("on_timeout", self.on_timeout)
        self.network.set_callback("on_undo_update", self.on_undo_update)
        self.network.set_callback("on_rematch_request", self.on_rematch_request)
        self.network.set_callback("on_rematch_response", self.on_rematch_response)

    
    def on_connect(self):
        """连接成功回调"""
        print("已连接到服务器")
        self.connected = True
        self.status_message = "已连接到服务器，正在寻找对手..."
        self.network.find_game()
    
    def on_disconnect(self):
        """断开连接回调"""
        print("与服务器断开连接")
        self.connected = False
        self.status_message = "与服务器断开连接"
        
        # 如果在等待对手阶段，直接返回，不处理游戏结束逻辑
        if self.waiting_for_opponent:
            print("在等待对手界面断开连接")
            return
            
        # 断线重连处理或其他操作可以在这里添加
        
        # 不在这里处理游戏结束逻辑，而是依赖server发送的opponent_disconnected消息
        # 这个消息会在handle_message中被转发为game_over消息，并在on_game_over中处理
        print("断开连接，等待服务器通知对方断开状态")
    
    def on_waiting(self, data):
        """等待匹配回调"""
        print("正在寻找对手...")
        self.status_message = "正在寻找对手..."
        self.waiting_for_opponent = True
    
    def on_match_found(self, data):
        """匹配成功回调"""
        print("找到对手！")
        self.waiting_for_opponent = False  # 找到对手，不再等待
        self.role = data.get("role")  # "black" 或 "white"
        self.opponent_name = data.get("opponent")
        self.is_my_turn = (self.role == "black")  # 黑棋先行
        
        # 重置游戏状态
        self.game_over = data.get("game_over", False)
        self.winner = None
        self.board = [[Piece.EMPTY for _ in range(self.board_size)] for _ in range(self.board_size)]
        self.move_history = []
        self.show_game_over_dialog = False
        self.rematch_requested = False
        self.opponent_rematch_requested = False
        self.ranking_updated = False
        
        # 重置悔棋次数
        self.black_undo_count = 0
        self.white_undo_count = 0
        
        # 更新计时器
        black_time = data.get("black_time")
        white_time = data.get("white_time")
        if black_time is not None:
            self.black_time_left = black_time
        else:
            self.black_time_left = self.turn_time_limit
            
        if white_time is not None:
            self.white_time_left = white_time
        else:
            self.white_time_left = self.turn_time_limit
            
        self.last_time_update = pygame.time.get_ticks()
        
        if self.role == "black":
            self.status_message = f"对战开始！您执黑棋，对手: {self.opponent_name}"
        else:
            self.status_message = f"对战开始！您执白棋，对手: {self.opponent_name}"
        
        # 添加系统消息
        self.add_chat_message("系统", f"对战开始！您执{'黑' if self.role == 'black' else '白'}棋，对手: {self.opponent_name}")
    
    def on_move(self, data):
        """落子回调"""
        x = data.get("x")
        y = data.get("y")
        piece = data.get("piece")  # "black" 或 "white"
        next_player = data.get("next_player")  # "black" 或 "white"
        
        # 更新棋盘
        self.board[y][x] = Piece.BLACK if piece == "black" else Piece.WHITE
        
        # 记录落子历史
        current_piece = Piece.BLACK if piece == "black" else Piece.WHITE
        self.move_history.append((x, y, current_piece))
        
        # 播放落子音效
        if self.down_sound:
            self.down_sound.play()
        
        # 更新当前玩家
        self.is_my_turn = (next_player == self.role)
        
        # 更新计时器
        black_time = data.get("black_time")
        white_time = data.get("white_time")
        if black_time is not None:
            self.black_time_left = black_time
        if white_time is not None:
            self.white_time_left = white_time
        self.last_time_update = pygame.time.get_ticks()
        
        # 检查游戏是否结束
        if data.get("game_over"):
            self.game_over = True
            self.winner = data.get("winner")
            
            if (self.role == "black" and self.winner == "black") or (self.role == "white" and self.winner == "white"):
                self.status_message = "恭喜您获胜！"
                if self.win_sound:
                    self.win_sound.play()
            else:
                self.status_message = "很遗憾，您输了！"
                if self.lose_sound:
                    self.lose_sound.play()
                    
            # 立即显示游戏结束对话框
            self.show_game_over_dialog = True
            print(f"游戏结束(落子胜利): winner={self.winner}, show_dialog={self.show_game_over_dialog}")
            
            # 添加系统消息
            self.add_chat_message("系统", self.status_message)
        else:
            if self.is_my_turn:
                self.status_message = "轮到您落子"
            else:
                self.status_message = "等待对手落子..."
    
    def on_chat(self, data):
        """聊天消息回调"""
        username = data.get("username")
        content = data.get("content")
        timestamp = data.get("timestamp")
        
        self.add_chat_message(username, content, timestamp)
    
    def on_game_over(self, data):
        """游戏结束回调"""
        # 如果已经处于游戏结束状态，则不重复处理
        if self.game_over and self.show_game_over_dialog:
            return
            
        self.game_over = True
        self.winner = data.get("winner")
        reason = data.get("reason")
        message = data.get("message")
        has_moves = data.get("has_moves", True)  # 默认为True，兼容旧版本
        
        # 检查是否是对方断开连接导致的游戏结束
        if reason == "opponent_disconnected":
            # 如果游戏已经结束，不再显示获胜信息
            if self.game_over and self.winner is not None and self.winner != "you" and self.winner != self.role:
                print("游戏已结束且已有胜负，忽略对方断开连接")
                return
            else:
                # 设置游戏为已结束状态
                self.game_over = True
                # 不设置获胜者，只显示对方断开连接
                self.winner = None
                self.status_message = "对手已断开连接"
                # 添加一个标志表示是因为对方断开连接而结束游戏
                self.opponent_disconnected = True
                # 不播放任何音效，因为这不是胜利或失败
        elif reason == "surrender":
            print("对手投降")
            if (self.role == "black" and self.winner == "black") or (self.role == "white" and self.winner == "white"):
                # 不管是否有落子历史，都显示胜利信息
                self.status_message = "对手投降，您获胜！"
                print("对手投降，您获胜！")
                if self.win_sound:
                    self.win_sound.play()
            else:
                self.status_message = "您已投降，游戏结束"
                print("您已投降，游戏结束")
                if self.lose_sound:
                    self.lose_sound.play()
        elif reason == "timeout":
            if (self.role == "black" and self.winner == "black") or (self.role == "white" and self.winner == "white"):
                self.status_message = "对手超时，您获胜！"
                if self.win_sound:
                    self.win_sound.play()
            else:
                self.status_message = "您已超时，游戏结束"
                if self.lose_sound:
                    self.lose_sound.play()
        else:
            if (self.role == "black" and self.winner == "black") or (self.role == "white" and self.winner == "white"):
                self.status_message = "恭喜您获胜！"
                if self.win_sound:
                    self.win_sound.play()
            else:
                self.status_message = "很遗憾，您输了！"
                if self.lose_sound:
                    self.lose_sound.play()
        
        # 添加系统消息
        self.add_chat_message("系统", message or self.status_message)
        
        # 立即显示游戏结束对话框，确保第一时间显示
        self.show_game_over_dialog = True
        self.rematch_requested = False
        self.opponent_rematch_requested = False
        
        # 打印调试信息，确认游戏结束状态
        print(f"游戏结束: winner={self.winner}, reason={reason}, show_dialog={self.show_game_over_dialog}")
    
    def on_error(self, error_message):
        """错误回调"""
        print(f"错误: {error_message}")
        self.status_message = f"错误: {error_message}"
        self.add_chat_message("系统", f"错误: {error_message}")
    
    def on_undo_request(self, data):
        """收到对方的悔棋请求"""
        username = data.get("username", self.opponent_name)
        self.undo_requester = username
        self.pending_undo_request = True
        # 添加显示对话框的标志
        self.show_undo_request_dialog = True
        self.add_chat_message("系统", f"对手 {username} 请求悔棋，请回应")
        self.status_message = f"对手请求悔棋，请回应"
        # 添加调试信息
        print(f"收到悔棋请求: {data}")
    
    def on_undo_response(self, data):
        """收到对方对悔棋请求的回应"""
        allowed = data.get("allowed", False)
        username = data.get("username")
        
        # 添加调试信息
        print(f"收到悔棋回应: {data}, 是否同意: {allowed}")
        
        if allowed:
            # 对方同意悔棋
            self.add_chat_message("系统", f"对手 {username} 同意了您的悔棋请求")
            self.status_message = "悔棋成功，等待服务器更新棋盘..."
            
            # 更新悔棋次数
            if self.role == "black":
                self.black_undo_count += 1
            else:
                self.white_undo_count += 1
            
            # 重置悔棋状态
            self.undo_requested = False
            self.undo_allowed = True
            
            # 注意：实际的棋盘更新将在收到 on_undo_update 消息时进行
            # 在这里我们不自行更新棋盘，以避免和服务器的更新冲突
            
        else:
            # 对方拒绝悔棋
            self.add_chat_message("系统", f"对手 {username} 拒绝了您的悔棋请求")
            self.status_message = "对方拒绝了您的悔棋请求，请继续游戏"
            self.undo_requested = False
    
    def on_timeout(self, data):
        """超时回调"""
        self.game_over = True
        self.winner = data.get("winner")
        
        if (self.role == "black" and self.winner == "black") or (self.role == "white" and self.winner == "white"):
            self.status_message = "对手超时，您获胜！"
            if self.win_sound:
                self.win_sound.play()
        else:
            self.status_message = "您已超时，游戏结束"
            if self.lose_sound:
                self.lose_sound.play()
        
        # 添加系统消息
    def add_chat_message(self, username, content, timestamp=None):
        """添加聊天消息"""
        if timestamp is None:
            timestamp = pygame.time.get_ticks()
        
        # 检查是否是表情消息
        is_emoji = False
        emoji_id = None
        
        if content.startswith("[emoji:") and content.endswith("]"):
            try:
                emoji_id = content[7:-1]  # 提取表情ID
                is_emoji = True
            except:
                pass
        
        self.chat_messages.append({
            "username": username,
            "content": content,
            "timestamp": timestamp,
            "is_emoji": is_emoji,
            "emoji_id": emoji_id
        })
        
        # 限制聊天消息数量
        if len(self.chat_messages) > 50:
            self.chat_messages = self.chat_messages[-50:]
    
    def update_timer(self):
        """更新计时器"""
        # 如果游戏结束，不更新计时器
        if self.game_over:
            return
            
        # 如果还没有开始游戏（没有角色分配），不更新计时器
        if self.role is None or self.opponent_name is None:
            return
            
        # 如果游戏刚开始，没有任何落子，不更新计时器
        if not self.move_history:
            return
            
        # 如果有待处理的悔棋请求，不更新计时器
        if self.pending_undo_request or self.undo_requested:
            return
        
        current_time = pygame.time.get_ticks()
        elapsed = (current_time - self.last_time_update) / 1000.0  # 转换为秒
        self.last_time_update = current_time
        
        # 更新当前玩家的剩余时间
        if self.is_my_turn:  # 如果是自己的回合
            if self.role == "black":
                self.black_time_left -= elapsed
                if self.black_time_left <= 0:
                    self.black_time_left = 0
                    # 发送超时消息
                    self.network.send_message({
                        "type": "timeout"
                    })
                    self.game_over = True
                    self.winner = "white"
                    self.status_message = "您已超时，对方获胜"
                    if self.lose_sound:
                        self.lose_sound.play()
            else:  # 自己是白棋
                self.white_time_left -= elapsed
                if self.white_time_left <= 0:
                    self.white_time_left = 0
                    # 发送超时消息
                    self.network.send_message({
                        "type": "timeout"
                    })
                    self.game_over = True
                    self.winner = "black"
                    self.status_message = "您已超时，对方获胜"
                    if self.lose_sound:
                        self.lose_sound.play()
        else:  # 如果是对手的回合
            if self.role == "black":  # 自己是黑棋，对手是白棋
                self.white_time_left -= elapsed
                if self.white_time_left <= 0:
                    self.white_time_left = 0
                    # 白棋已超时，但等待服务器确认
            else:  # 自己是白棋，对手是黑棋
                self.black_time_left -= elapsed
                if self.black_time_left <= 0:
                    self.black_time_left = 0
                    # 黑棋已超时，但等待服务器确认
    
    def handle_event(self, event):
        """处理事件"""
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:  # 左键点击
                x, y = event.pos
                
                # 如果显示游戏结束对话框，处理对话框内的点击
                if self.show_game_over_dialog and self.game_over:
                    # 检查是否点击了关闭对话框的区域
                    if hasattr(self, 'close_dialog_rect') and self.close_dialog_rect.collidepoint(x, y):
                        self.show_game_over_dialog = False
                        
                        # 如果是对手断开连接导致的游戏结束，则自动返回菜单
                        if self.opponent_disconnected:
                            print("对手断开连接，自动返回菜单")
                            # 延迟一小段时间，让用户看到消息
                            pygame.time.delay(500)
                            # 返回菜单
                            self.game.return_to_menu()
                            
                    return  # 游戏结束对话框显示时不处理其他点击
                
                # 如果显示悔棋请求对话框，处理对话框内的点击
                if hasattr(self, 'show_undo_request_dialog') and self.show_undo_request_dialog:
                    # 检查是否点击了同意按钮
                    if hasattr(self, 'undo_agree_button_rect') and self.undo_agree_button_rect.collidepoint(x, y):
                        print("点击了悔棋同意按钮")
                        self.network.respond_to_undo(True)
                        self.pending_undo_request = False
                        self.show_undo_request_dialog = False
                        self.add_chat_message("系统", f"您同意了对手的悔棋请求")
                        return
                    
                    # 检查是否点击了拒绝按钮
                    if hasattr(self, 'undo_disagree_button_rect') and self.undo_disagree_button_rect.collidepoint(x, y):
                        print("点击了悔棋拒绝按钮")
                        self.network.respond_to_undo(False)
                        self.pending_undo_request = False
                        self.show_undo_request_dialog = False
                        self.add_chat_message("系统", f"您拒绝了对手的悔棋请求")
                        return
                    return  # 悔棋请求对话框显示时不处理其他点击
                
                # 如果显示重新开始游戏请求对话框，处理对话框内的点击
                if hasattr(self, 'show_rematch_request_dialog') and self.show_rematch_request_dialog:
                    # 检查是否点击了同意按钮
                    if hasattr(self, 'rematch_agree_button_rect') and self.rematch_agree_button_rect.collidepoint(x, y):
                        self.network.respond_to_rematch(True)
                        self.opponent_rematch_requested = False
                        self.show_rematch_request_dialog = False
                        self.add_chat_message("系统", "您同意了再来一局")
                        return
                    
                    # 检查是否点击了拒绝按钮
                    if hasattr(self, 'rematch_disagree_button_rect') and self.rematch_disagree_button_rect.collidepoint(x, y):
                        self.network.respond_to_rematch(False)
                        self.opponent_rematch_requested = False
                        self.show_rematch_request_dialog = False
                        self.add_chat_message("系统", "您拒绝了再来一局")
                        return
                    return  # 重新开始游戏请求对话框显示时不处理其他点击
                
                # 游戏结束状态下，处理再来一局相关按钮
                if self.game_over:
                    # 检查是否点击了再来一局按钮
                    if not self.rematch_requested and not self.opponent_rematch_requested and self.rematch_button_rect.collidepoint(x, y):
                        self.network.request_rematch()
                        self.rematch_requested = True
                        self.add_chat_message("系统", "已发送再来一局请求，等待对方回应...")
                        return
                    
                    # 如果对方请求再来一局，检查是否点击了同意/拒绝按钮
                    if self.opponent_rematch_requested:
                        if self.accept_rematch_rect.collidepoint(x, y):
                            self.network.respond_to_rematch(True)
                            self.add_chat_message("系统", "您同意了再来一局")
                            self.opponent_rematch_requested = False
                            # 等待服务器发送match_found消息
                            return
                        
                        if self.reject_rematch_rect.collidepoint(x, y):
                            self.network.respond_to_rematch(False)
                            self.add_chat_message("系统", "您拒绝了再来一局")
                            self.opponent_rematch_requested = False
                            return
                
                # 检查是否点击了返回菜单按钮
                if self.back_button_rect.collidepoint(x, y):
                    # 记录当前状态用于日志
                    status = "已结束" if self.game_over else "未结束"
                    has_moves = "有落子" if self.move_history else "无落子"
                    print(f"点击返回菜单按钮：游戏{status}，{has_moves}，连接状态：{self.connected}")
                    
                    # 无论任何状态，都先尝试安全断开连接
                    if self.connected:
                        try:
                            # 不做投降处理，直接发送断开连接消息
                            print("发送断开连接消息")
                            self.network.send_message({"type": "client_disconnect"})
                            # 等待一小段时间确保消息发送完成
                            pygame.time.delay(200)
                        except Exception as e:
                            print(f"发送断开消息时出错: {e}")
                    
                    # 确保断开网络连接
                    try:
                        print("执行断开连接")
                        self.network.disconnect()
                        # 重置网络客户端状态
                        self.network = NetworkClient()
                    except Exception as e:
                        print(f"断开连接时出错: {e}")
                    
                    # 返回菜单
                    self.game.return_to_menu()
                    return
                
                # 检查是否点击了投降按钮
                if not self.game_over and self.surrender_button_rect.collidepoint(x, y):
                    self.network.surrender()
                    return
                
                # 检查是否点击了悔棋按钮
                if not self.game_over and self.undo_button_rect.collidepoint(x, y):
                    self.request_undo()
                    return
                
                # 检查是否点击了同意悔棋按钮
                if self.pending_undo_request and self.agree_button_rect.collidepoint(x, y):
                    self.network.respond_to_undo(True)
                    self.pending_undo_request = False
                    self.add_chat_message("系统", f"您同意了对手的悔棋请求")
                    return
                
                # 检查是否点击了拒绝悔棋按钮
                if self.pending_undo_request and self.disagree_button_rect.collidepoint(x, y):
                    self.network.respond_to_undo(False)
                    self.pending_undo_request = False
                    self.add_chat_message("系统", f"您拒绝了对手的悔棋请求")
                    return
                
                # 检查是否点击了发送按钮
                if self.send_button_rect.collidepoint(x, y) and self.chat_input.strip():
                    self.network.send_chat(self.chat_input.strip())
                    self.chat_input = ""
                    return
                
                # 检查是否点击了表情按钮
                if self.emoji_button_rect.collidepoint(x, y):
                    self.show_emoji_panel = not self.show_emoji_panel
                    return
                
                # 如果表情面板显示，检查是否点击了表情
                if self.show_emoji_panel and self.emoji_panel_rect.collidepoint(x, y):
                    emoji_size = 28  # 与渲染时保持一致
                    padding = 15  # 与渲染时保持一致
                    cols = 3
                    
                    # 计算面板内部可用区域
                    panel_width = self.emoji_panel_rect.width - (padding * 2)
                    panel_height = self.emoji_panel_rect.height - (padding * 2)
                    
                    # 计算每行最多放几个表情
                    max_cols = min(cols, len(self.emoji_images))
                    max_rows = (len(self.emoji_images) + max_cols - 1) // max_cols
                    
                    for i, (emoji_id, emoji_img) in enumerate(self.emoji_images.items()):
                        row = i // max_cols
                        col = i % max_cols
                        
                        # 计算表情位置，确保与渲染时一致
                        emoji_x = self.emoji_panel_rect.x + padding + col * ((panel_width - (max_cols-1)*padding) // max_cols + padding)
                        emoji_y = self.emoji_panel_rect.y + padding + row * ((panel_height - (max_rows-1)*padding) // max_rows + padding)
                        emoji_rect = pygame.Rect(emoji_x, emoji_y, emoji_size, emoji_size)
                        
                        if emoji_rect.collidepoint(x, y):
                            # 发送表情消息
                            self.network.send_chat(f"[emoji:{emoji_id}]")
                            self.show_emoji_panel = False
                            return
                else:
                    # 如果点击了其他地方，关闭表情面板
                    self.show_emoji_panel = False
                
                # 检查是否点击了聊天输入框
                if self.chat_input_rect.collidepoint(x, y):
                    self.chat_active = True
                    return
                else:
                    self.chat_active = False
                
                # 只有在游戏未结束且轮到自己时才处理棋盘点击
                if not self.game_over and self.is_my_turn and self.board_rect.collidepoint(x, y):
                    # 检查是否有待处理的悔棋请求，如果有则不允许落子
                    if self.pending_undo_request:
                        self.add_chat_message("系统", "请先回应对方的悔棋请求")
                        return
                    
                    # 计算棋盘坐标
                    board_x = round((x - self.board_x) / self.cell_size)
                    board_y = round((y - self.board_y) / self.cell_size)
                    
                    # 确保坐标在有效范围内
                    if 0 <= board_x < self.board_size and 0 <= board_y < self.board_size:
                        # 检查该位置是否为空
                        if self.board[board_y][board_x] == Piece.EMPTY:
                            # 记录落子历史
                            current_piece = Piece.BLACK if self.role == "black" else Piece.WHITE
                            self.move_history.append((board_x, board_y, current_piece))
                            
                            # 发送落子消息到服务器
                            self.network.make_move(board_x, board_y)
        
        elif event.type == pygame.KEYDOWN:
            # 处理聊天输入
            if self.chat_active:
                if event.key == pygame.K_RETURN:
                    if self.chat_input.strip():
                        self.network.send_chat(self.chat_input.strip())
                        self.chat_input = ""
                elif event.key == pygame.K_BACKSPACE:
                    self.chat_input = self.chat_input[:-1]
                else:
                    # 添加字符到输入框
                    if event.unicode.isprintable():
                        self.chat_input += event.unicode
    
    def request_undo(self):
        """请求悔棋"""
        # 检查是否有棋子可以悔棋
        if not self.move_history:
            self.add_chat_message("系统", "您还没有落子，无法悔棋")
            return
            
        # 检查是否有自己的棋子可以悔棋
        has_own_move = False
        for _, _, piece in self.move_history:
            if (self.role == "black" and piece == Piece.BLACK) or (self.role == "white" and piece == Piece.WHITE):
                has_own_move = True
                break
                
        if not has_own_move:
            self.add_chat_message("系统", "您还没有落子，无法悔棋")
            return
            
        # 检查是否已达到本回合悔棋次数限制
        current_undo_count = self.black_undo_count if self.role == "black" else self.white_undo_count
        if current_undo_count >= self.max_undo_per_turn:
            self.add_chat_message("系统", f"您本回合已使用悔棋{current_undo_count}次，不能再悔棋")
            return
            
        # 检查其他条件
        if self.undo_requested or self.game_over:
            return
            
        # 检查是否有待处理的悔棋请求
        if self.pending_undo_request:
            self.add_chat_message("系统", "请先回应对方的悔棋请求")
            return
        
        # 防止多次点击
        current_time = pygame.time.get_ticks()
        if current_time - self.last_undo_time < 1000:  # 1秒内不能连续请求
            return
        
        self.last_undo_time = current_time
        self.undo_requested = True
        self.status_message = "已发送悔棋请求，等待对方回应..."
        
        # 发送悔棋请求
        self.network.send_message({
            "type": "undo_request"
        })
        
        # 添加系统消息
        self.add_chat_message("系统", "已发送悔棋请求，等待对方回应...")
    
    def render(self):
        """渲染游戏界面"""
        # 更新计时器
        self.update_timer()
        
        # 填充背景
        self.screen.fill(self.light_gray)
        
        # 绘制游戏标题
        title_text = self.title_font.render("五子棋 - 网络对战", True, (80, 80, 80))
        title_rect = title_text.get_rect(centerx=self.width//2, top=15)
        self.screen.blit(title_text, title_rect)
        
        # 绘制返回菜单按钮（始终显示）
        mouse_pos = pygame.mouse.get_pos()
        button_color = self.apple_light_blue if self.back_button_rect.collidepoint(mouse_pos) else self.apple_blue
        pygame.draw.rect(self.screen, button_color, self.back_button_rect, 0, 8)
        back_text = self.info_font.render(self.back_button_text, True, self.white)
        back_text_rect = back_text.get_rect(center=self.back_button_rect.center)
        self.screen.blit(back_text, back_text_rect)
        
        # 如果正在等待对手，显示等待画面
        if self.waiting_for_opponent:
            self.render_waiting_screen()
            return
        
        # 绘制状态信息
        status_text = self.info_font.render(self.status_message, True, self.apple_blue)
        status_rect = status_text.get_rect(centerx=self.width//2, top=70)
        self.screen.blit(status_text, status_rect)
        
        # 绘制计时器 - 移到左上角
        # 黑棋计时器
        black_timer_rect = pygame.Rect(10, 90, 120, 50)
        pygame.draw.rect(self.screen, (50, 50, 50), black_timer_rect, 0, 8)
        black_timer_text = self.timer_font.render(f"{int(self.black_time_left)}秒", True, self.white)
        black_timer_text_rect = black_timer_text.get_rect(center=black_timer_rect.center)
        self.screen.blit(black_timer_text, black_timer_text_rect)
        
        # 白棋计时器
        white_timer_rect = pygame.Rect(10, 200, 120, 50)
        pygame.draw.rect(self.screen, self.white, white_timer_rect, 0, 8)
        white_timer_text = self.timer_font.render(f"{int(self.white_time_left)}秒", True, self.black)
        white_timer_text_rect = white_timer_text.get_rect(center=white_timer_rect.center)
        self.screen.blit(white_timer_text, white_timer_text_rect)
        
        # 绘制计时器标签
        black_label = self.info_font.render("黑棋时间:", True, self.black)
        black_label_rect = black_label.get_rect(bottom=black_timer_rect.top - 5, centerx=black_timer_rect.centerx)
        self.screen.blit(black_label, black_label_rect)
        
        white_label = self.info_font.render("白棋时间:", True, self.black)
        white_label_rect = white_label.get_rect(bottom=white_timer_rect.top - 5, centerx=white_timer_rect.centerx)
        self.screen.blit(white_label, white_label_rect)
        
        # 返回菜单按钮已在前面绘制
        
        # 绘制投降按钮
        button_color = self.apple_light_blue if self.surrender_button_rect.collidepoint(mouse_pos) else self.apple_blue
        pygame.draw.rect(self.screen, button_color, self.surrender_button_rect, 0, 8)
        surrender_text = self.info_font.render(self.surrender_button_text, True, self.white)
        surrender_text_rect = surrender_text.get_rect(center=self.surrender_button_rect.center)
        self.screen.blit(surrender_text, surrender_text_rect)
        
        # 绘制悔棋按钮
        button_color = self.apple_light_blue if self.undo_button_rect.collidepoint(mouse_pos) else self.apple_blue
        pygame.draw.rect(self.screen, button_color, self.undo_button_rect, 0, 8)
        undo_text = self.info_font.render(self.undo_button_text, True, self.white)
        undo_text_rect = undo_text.get_rect(center=self.undo_button_rect.center)
        self.screen.blit(undo_text, undo_text_rect)
        
        # 如果游戏已结束，渲染再来一局相关按钮
        if self.game_over:
            if self.opponent_rematch_requested and not hasattr(self, 'show_rematch_request_dialog'):
                # 对方请求再来一局，显示同意/拒绝按钮（旧的按钮显示方式，保留兼容性）
                
                # 显示提示信息
                rematch_notice = self.info_font.render("对方请求再来一局", True, self.apple_blue)
                rematch_notice_rect = rematch_notice.get_rect(centerx=self.width - 160, y=280)
                self.screen.blit(rematch_notice, rematch_notice_rect)
                
                # 同意按钮
                button_color = self.apple_light_blue if self.accept_rematch_rect.collidepoint(mouse_pos) else self.apple_blue
                pygame.draw.rect(self.screen, button_color, self.accept_rematch_rect, 0, 8)
                text = self.info_font.render(self.accept_rematch_text, True, self.white)
                text_rect = text.get_rect(center=self.accept_rematch_rect.center)
                self.screen.blit(text, text_rect)
                
                # 拒绝按钮
                button_color = self.apple_light_blue if self.reject_rematch_rect.collidepoint(mouse_pos) else self.apple_blue
                pygame.draw.rect(self.screen, button_color, self.reject_rematch_rect, 0, 8)
                text = self.info_font.render(self.reject_rematch_text, True, self.white)
                text_rect = text.get_rect(center=self.reject_rematch_rect.center)
                self.screen.blit(text, text_rect)
                
            elif not self.rematch_requested:
                # 没有请求过再来一局，显示请求按钮
                button_color = self.apple_light_blue if self.rematch_button_rect.collidepoint(mouse_pos) else self.apple_blue
                pygame.draw.rect(self.screen, button_color, self.rematch_button_rect, 0, 8)
                text = self.info_font.render(self.rematch_button_text, True, self.white)
                text_rect = text.get_rect(center=self.rematch_button_rect.center)
                self.screen.blit(text, text_rect)
                
            elif self.rematch_requested:
                # 已经请求过再来一局，显示等待状态
                pygame.draw.rect(self.screen, (150, 150, 150), self.rematch_button_rect, 0, 8)
                text = self.info_font.render("等待对方回应...", True, self.white)
                text_rect = text.get_rect(center=self.rematch_button_rect.center)
                self.screen.blit(text, text_rect)
        
        # 绘制棋盘背景
        pygame.draw.rect(self.screen, self.board_color, self.board_rect)
        
        # 绘制棋盘网格
        for i in range(self.board_size):
            # 横线
            thickness = 5 if i == 0 or i == (self.board_size - 1) else 2
            pygame.draw.line(
                self.screen,
                self.black,
                (self.board_x, self.board_y + i * self.cell_size),
                (self.board_x + self.board_width, self.board_y + i * self.cell_size),
                thickness
            )
            # 竖线
            pygame.draw.line(
                self.screen,
                self.black,
                (self.board_x + i * self.cell_size, self.board_y),
                (self.board_x + i * self.cell_size, self.board_y + self.board_width),
                thickness
            )
        
        # 绘制棋盘上的五个点（天元和星）
        star_points = [(3, 3), (3, 11), (7, 7), (11, 3), (11, 11)]
        for x, y in star_points:
            pygame.draw.circle(
                self.screen,
                self.black,
                (self.board_x + x * self.cell_size, self.board_y + y * self.cell_size),
                10
            )
        
        # 绘制棋子
        for y in range(self.board_size):
            for x in range(self.board_size):
                if self.board[y][x] != Piece.EMPTY:
                    piece_x = self.board_x + x * self.cell_size
                    piece_y = self.board_y + y * self.cell_size
                    
                    if self.board[y][x] == Piece.BLACK:  # 黑棋
                        if self.black_piece:
                            piece_rect = self.black_piece.get_rect(center=(piece_x, piece_y))
                            self.screen.blit(self.black_piece, piece_rect)
                        else:
                            pygame.draw.circle(self.screen, self.black, (piece_x, piece_y), int(self.cell_size * 0.45))
                    else:  # 白棋
                        if self.white_piece:
                            piece_rect = self.white_piece.get_rect(center=(piece_x, piece_y))
                            self.screen.blit(self.white_piece, piece_rect)
                        else:
                            pygame.draw.circle(self.screen, self.white, (piece_x, piece_y), int(self.cell_size * 0.45))
        
        # 绘制聊天区域
        # 聊天历史背景
        pygame.draw.rect(self.screen, (245, 245, 245), self.chat_history_rect, 0, 8)
        pygame.draw.rect(self.screen, self.gray, self.chat_history_rect, 2, 8)
        
        # 聊天输入框
        pygame.draw.rect(self.screen, self.white, self.chat_input_rect, 0, 8)
        pygame.draw.rect(self.screen, self.gray, self.chat_input_rect, 2, 8)
        
        # 发送按钮
        button_color = self.apple_light_blue if self.send_button_rect.collidepoint(mouse_pos) else self.apple_blue
        pygame.draw.rect(self.screen, button_color, self.send_button_rect, 0, 8)
        send_text = self.chat_font.render("发送", True, self.white)
        send_text_rect = send_text.get_rect(center=self.send_button_rect.center)
        self.screen.blit(send_text, send_text_rect)
        
        # 表情按钮 - 使用表情图片作为图标
        emoji_button_color = self.apple_light_blue if self.emoji_button_rect.collidepoint(mouse_pos) else self.apple_blue
        pygame.draw.rect(self.screen, emoji_button_color, self.emoji_button_rect, 0, 8)
        # 使用第一个表情作为按钮图标
        if "1" in self.emoji_images:
            emoji_icon = self.emoji_images["1"]
            emoji_icon_rect = emoji_icon.get_rect(center=self.emoji_button_rect.center)
            self.screen.blit(emoji_icon, emoji_icon_rect)
        
        # 如果表情面板显示，绘制表情面板
        if self.show_emoji_panel:
            pygame.draw.rect(self.screen, self.white, self.emoji_panel_rect, 0, 8)
            pygame.draw.rect(self.screen, self.gray, self.emoji_panel_rect, 2, 8)
            
            # 绘制表情 - 严格统一大小和位置
            emoji_size = 28  # 稍微减小表情大小
            padding = 15  # 增加间距
            cols = 3
            
            # 计算面板内部可用区域
            panel_width = self.emoji_panel_rect.width - (padding * 2)
            panel_height = self.emoji_panel_rect.height - (padding * 2)
            
            # 计算每行最多放几个表情
            max_cols = min(cols, len(self.emoji_images))
            max_rows = (len(self.emoji_images) + max_cols - 1) // max_cols
            
            # 绘制表情网格
            for i, (emoji_id, emoji_img) in enumerate(self.emoji_images.items()):
                row = i // max_cols
                col = i % max_cols
                
                # 计算表情位置，确保居中
                x = self.emoji_panel_rect.x + padding + col * ((panel_width - (max_cols-1)*padding) // max_cols + padding)
                y = self.emoji_panel_rect.y + padding + row * ((panel_height - (max_rows-1)*padding) // max_rows + padding)
                
                # 创建表情按钮区域
                emoji_rect = pygame.Rect(x, y, emoji_size, emoji_size)
                
                # 确保表情大小严格统一
                scaled_emoji = pygame.transform.scale(emoji_img, (emoji_size, emoji_size))
                
                # 绘制表情
                self.screen.blit(scaled_emoji, emoji_rect)
        
        # 绘制聊天输入文本
        # 处理输入文本的换行显示
        max_input_width = self.chat_input_rect.width - 70  # 留出发送按钮的空间
        input_text = self.chat_font.render(self.chat_input, True, self.black)
        
        if input_text.get_width() > max_input_width:
            # 如果文本太长，只显示末尾部分
            visible_chars = 0
            test_text = ""
            for i in range(len(self.chat_input) - 1, -1, -1):
                test_text = self.chat_input[i] + test_text
                if self.chat_font.render(test_text, True, self.black).get_width() > max_input_width:
                    break
                visible_chars += 1
            
            visible_text = self.chat_input[-visible_chars:]
            input_text = self.chat_font.render(visible_text, True, self.black)
        
        input_text_rect = input_text.get_rect(x=self.chat_input_rect.x + 10, centery=self.chat_input_rect.centery)
        self.screen.blit(input_text, input_text_rect)
        
        # 绘制聊天历史
        chat_title = self.info_font.render("聊天", True, self.black)
        chat_title_rect = chat_title.get_rect(centerx=self.chat_history_rect.centerx, y=self.chat_history_rect.y + 10)
        self.screen.blit(chat_title, chat_title_rect)
        
        # 绘制聊天消息
        y_offset = self.chat_history_rect.y + 50
        for message in reversed(self.chat_messages[-10:]):  # 只显示最近的10条消息
            username = message["username"]
            content = message["content"]
            is_emoji = message.get("is_emoji", False)
            emoji_id = message.get("emoji_id")
            
            # 用户名
            username_text = self.chat_font.render(f"{username}:", True, self.apple_blue)
            username_rect = username_text.get_rect(x=self.chat_history_rect.x + 10, y=y_offset)
            self.screen.blit(username_text, username_rect)
            
            # 如果是表情消息
            if is_emoji and emoji_id in self.emoji_images:
                # 绘制表情 - 确保大小统一
                emoji_img = self.emoji_images[emoji_id]
                emoji_size = 28  # 统一表情大小，与其他地方保持一致
                scaled_emoji = pygame.transform.scale(emoji_img, (emoji_size, emoji_size))
                emoji_rect = scaled_emoji.get_rect(x=self.chat_history_rect.x + 15, y=y_offset + 25)
                self.screen.blit(scaled_emoji, emoji_rect)
                
                # 更新下一条消息的位置
                y_offset += 25 + emoji_size + 10
            else:
                # 内容 - 处理长文本自动换行
                max_width = self.chat_history_rect.width - 20
                
                # 中文和英文混合文本的换行处理
                lines = []
                current_line = ""
                
                # 逐字符处理，确保中文也能正确换行
                for char in content:
                    test_line = current_line + char
                    test_text = self.chat_font.render(test_line, True, self.black)
                    if test_text.get_width() <= max_width:
                        current_line = test_line
                    else:
                        lines.append(current_line)
                        current_line = char
                
                if current_line:
                    lines.append(current_line)
                
                # 绘制每一行
                line_height = 25
                for i, line in enumerate(lines):
                    content_text = self.chat_font.render(line, True, self.black)
                    content_rect = content_text.get_rect(x=self.chat_history_rect.x + 10, y=y_offset + 25 + i * line_height)
                    self.screen.blit(content_text, content_rect)
                
                # 更新下一条消息的位置
                y_offset += 25 + len(lines) * line_height + 10
            
            # 如果超出聊天区域，则停止绘制
            if y_offset > self.chat_history_rect.bottom - 30:
                break
        
        # 如果有待处理的悔棋请求，显示悔棋回应按钮
        if self.pending_undo_request:
            # 同意按钮
            mouse_pos = pygame.mouse.get_pos()
            button_color = self.apple_light_blue if self.agree_button_rect.collidepoint(mouse_pos) else self.apple_blue
            pygame.draw.rect(self.screen, button_color, self.agree_button_rect, 0, 8)
            agree_text = self.info_font.render(self.agree_button_text, True, self.white)
            agree_text_rect = agree_text.get_rect(center=self.agree_button_rect.center)
            self.screen.blit(agree_text, agree_text_rect)
            
            # 拒绝按钮
            button_color = self.apple_light_blue if self.disagree_button_rect.collidepoint(mouse_pos) else self.apple_blue
            pygame.draw.rect(self.screen, button_color, self.disagree_button_rect, 0, 8)
            disagree_text = self.info_font.render(self.disagree_button_text, True, self.white)
            disagree_text_rect = disagree_text.get_rect(center=self.disagree_button_rect.center)
            self.screen.blit(disagree_text, disagree_text_rect)
        
        # 如果有悔棋请求对话框，优先显示
        if hasattr(self, 'show_undo_request_dialog') and self.show_undo_request_dialog:
            self.render_undo_request_dialog()
        # 否则，如果有重新开始游戏请求对话框，显示
        elif hasattr(self, 'show_rematch_request_dialog') and self.show_rematch_request_dialog:
            self.render_rematch_request_dialog()
        # 否则，如果游戏结束，显示游戏结束对话框
        elif self.game_over and self.show_game_over_dialog:
            self.render_game_over_dialog()
            
    
    def render_waiting_screen(self):
        """渲染等待对手的画面"""
        # 更新动画帧 - 加快动画速度，每30毫秒更新一次，使旋转更流畅
        current_time = pygame.time.get_ticks()
        if current_time - self.last_animation_update > 30:  # 每30毫秒更新一次
            self.waiting_animation_frame = (self.waiting_animation_frame + 1) % 36  # 36帧一个完整旋转
            self.last_animation_update = current_time
        
        # 绘制渐变背景
        for y in range(self.height):
            # 从顶部的浅灰色渐变到底部的白色
            color = (
                int(self.light_gray[0] * (1 - y/self.height) + self.white[0] * (y/self.height)),
                int(self.light_gray[1] * (1 - y/self.height) + self.white[1] * (y/self.height)),
                int(self.light_gray[2] * (1 - y/self.height) + self.white[2] * (y/self.height))
            )
            pygame.draw.line(self.screen, color, (0, y), (self.width, y))
        
        # 绘制等待图片并旋转
        if self.wait_img:
            # 根据动画帧计算旋转角度 - 使用更小的角度增量实现更平滑的旋转
            rotation_angle = self.waiting_animation_frame * 10  # 每帧旋转10度，36帧一圈
            rotated_img = pygame.transform.rotate(self.wait_img, rotation_angle)
            wait_rect = rotated_img.get_rect(center=(self.width//2, self.height//2 - 120))
            self.screen.blit(rotated_img, wait_rect)
        
        # 绘制状态信息 - 固定显示三个点而不是动态变化
        waiting_text = self.title_font.render("正在寻找对手...", True, self.apple_blue)
        waiting_rect = waiting_text.get_rect(center=(self.width//2, self.height//2 + 30))
        self.screen.blit(waiting_text, waiting_rect)
        
        # 绘制用户名
        username_text = self.info_font.render(f"用户名: {self.username}", True, self.black)
        username_rect = username_text.get_rect(center=(self.width//2, self.height//2 + 80))
        self.screen.blit(username_text, username_rect)
        
        # 绘制提示信息
        tip_text = self.info_font.render("请耐心等待，正在为您匹配对手...", True, (80, 80, 80))
        tip_rect = tip_text.get_rect(center=(self.width//2, self.height//2 + 240))
        self.screen.blit(tip_text, tip_rect)
        
        # 绘制装饰性棋盘
        board_size = 5  # 小型装饰棋盘
        cell_size = 30
        board_width = cell_size * (board_size - 1)
        board_x = self.width//2 - board_width//2
        board_y = self.height//2 + 60
        
        # 绘制棋盘背景
        board_rect = pygame.Rect(
            board_x - cell_size//2,
            board_y - cell_size//2,
            board_width + cell_size,
            board_width + cell_size
        )
        pygame.draw.rect(self.screen, self.board_color, board_rect)
        
        # 绘制棋盘网格
        for i in range(board_size):
            # 横线
            pygame.draw.line(
                self.screen,
                self.black,
                (board_x, board_y + i * cell_size),
                (board_x + board_width, board_y + i * cell_size),
                2
            )
            # 竖线
            pygame.draw.line(
                self.screen,
                self.black,
                (board_x + i * cell_size, board_y),
                (board_x + i * cell_size, board_y + board_width),
                2
            )
        
        # 绘制装饰性棋子
        piece_size = int(cell_size * 0.8)
        
        # 黑棋
        black_pos = [(1, 1), (3, 3)]
        for x, y in black_pos:
            piece_x = board_x + x * cell_size
            piece_y = board_y + y * cell_size
            if self.black_piece:
                scaled_black = pygame.transform.scale(self.black_piece, (piece_size, piece_size))
                piece_rect = scaled_black.get_rect(center=(piece_x, piece_y))
                self.screen.blit(scaled_black, piece_rect)
            else:
                pygame.draw.circle(self.screen, self.black, (piece_x, piece_y), piece_size//2)
        
        # 白棋
        white_pos = [(1, 3), (3, 1)]
        for x, y in white_pos:
            piece_x = board_x + x * cell_size
            piece_y = board_y + y * cell_size
            if self.white_piece:
                scaled_white = pygame.transform.scale(self.white_piece, (piece_size, piece_size))
                piece_rect = scaled_white.get_rect(center=(piece_x, piece_y))
                self.screen.blit(scaled_white, piece_rect)
            else:
                pygame.draw.circle(self.screen, self.white, (piece_x, piece_y), piece_size//2)
        
        # 绘制固定显示的返回提示文本（不再闪烁）
        hint_text = self.info_font.render("点击返回按钮可返回菜单", True, self.apple_blue)
        hint_rect = hint_text.get_rect(center=(self.width//2, self.height - 100))
        self.screen.blit(hint_text, hint_rect)
        
        # 绘制返回按钮
        mouse_pos = pygame.mouse.get_pos()
        button_color = self.apple_light_blue if self.back_button_rect.collidepoint(mouse_pos) else self.apple_blue
        pygame.draw.rect(self.screen, button_color, self.back_button_rect, 0, 8)
        back_text = self.info_font.render(self.back_button_text, True, self.white)
        back_text_rect = back_text.get_rect(center=self.back_button_rect.center)
        self.screen.blit(back_text, back_text_rect)
    
    def render_game_over_dialog(self):
        """渲染游戏结束对话框"""
        # 创建半透明背景
        overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 128))  # 半透明黑色
        self.screen.blit(overlay, (0, 0))
        
        # 计算中心位置
        center_x = self.width // 2
        center_y = self.height // 2
        
        # 确定当前情况
        is_winner = (self.role == "black" and self.winner == "black") or (self.role == "white" and self.winner == "white")
        is_disconnect = self.status_message and "断开连接" in self.status_message
        
        if is_disconnect:
            # 对方断开连接的情况 - 绘制简单的文本提示
            # 创建小型对话框
            dialog_width = 400
            dialog_height = 100
            dialog_x = (self.width - dialog_width) // 2
            dialog_y = (self.height - dialog_height) // 2
            dialog_rect = pygame.Rect(dialog_x, dialog_y, dialog_width, dialog_height)
            
            # 绘制对话框
            pygame.draw.rect(self.screen, self.white, dialog_rect, 0, 12)
            pygame.draw.rect(self.screen, self.apple_blue, dialog_rect, 3, 12)
            
            # 绘制断开连接消息
            message_text = self.info_font.render("对方已断开连接", True, self.black)
            message_rect = message_text.get_rect(center=dialog_rect.center)
            self.screen.blit(message_text, message_rect)
            
            # 绘制点击关闭提示（稍微往下移）
            tip_text = self.info_font.render("点击此处关闭", True, self.apple_blue)
            tip_rect = tip_text.get_rect(centerx=center_x, top=dialog_rect.bottom + 10)
            self.screen.blit(tip_text, tip_rect)
            
            # 保存关闭按钮区域
            self.close_dialog_rect = tip_rect.inflate(20, 20)
        else:
            # 胜利或失败情况 - 直接显示图片
            if is_winner and self.victory_img:
                # 胜利的情况
                img_rect = self.victory_img.get_rect(center=(center_x, center_y))
                self.screen.blit(self.victory_img, img_rect)
            elif not is_winner and self.lose_img:
                # 失败的情况
                img_rect = self.lose_img.get_rect(center=(center_x, center_y))
                self.screen.blit(self.lose_img, img_rect)
            
            # 绘制提示文本（放在图片下方）
            tip_text = self.info_font.render("点击此处关闭", True, self.apple_blue)
            tip_rect = tip_text.get_rect(centerx=center_x, top=center_y + 120)
            self.screen.blit(tip_text, tip_rect)
            
            # 保存关闭按钮区域
            self.close_dialog_rect = tip_rect.inflate(20, 20)
    
    def on_undo_update(self, data):
        """悔棋更新回调"""
        # 添加调试信息
        print(f"收到悔棋更新: {data}")
        
        # 更新棋盘状态
        board_data = data.get("board")
        if board_data:
            # 将服务器的棋盘状态转换为客户端的棋盘状态
            for y in range(self.board_size):
                for x in range(self.board_size):
                    if board_data[y][x] == 0:
                        self.board[y][x] = Piece.EMPTY
                    elif board_data[y][x] == 1:
                        self.board[y][x] = Piece.BLACK
                    elif board_data[y][x] == 2:
                        self.board[y][x] = Piece.WHITE
        
        # 更新当前玩家
        current_player = data.get("current_player")
        requester_role = data.get("requester_role")
        
        # 从移动历史中删除最后两步
        if len(self.move_history) >= 2:
            self.move_history = self.move_history[:-2]
        
        if current_player:
            self.is_my_turn = (current_player == self.role)
            
            # 根据是否是悔棋请求者设置不同的消息
            if requester_role == self.role:
                self.status_message = "悔棋成功，请重新落子"
            else:
                self.status_message = "对方悔棋成功，等待对方落子"
        
        # 更新计时器
        black_time = data.get("black_time")
        white_time = data.get("white_time")
        if black_time is not None:
            self.black_time_left = black_time
        if white_time is not None:
            self.white_time_left = white_time
        
        self.last_time_update = pygame.time.get_ticks()
    
    def on_rematch_request(self, data):
        """收到对方的重新比赛请求"""
        username = data.get("username", self.opponent_name)
        self.opponent_rematch_requested = True
        # 添加显示对话框的标志
        self.show_rematch_request_dialog = True
        # 确保游戏处于结束状态，这样才会显示同意/拒绝按钮
        self.game_over = True
        # 关闭游戏结束对话框，以便看到重新开始游戏请求对话框
        self.show_game_over_dialog = False
        self.add_chat_message("系统", f"对手 {username} 请求再来一局")
        
    def on_rematch_response(self, data):
        """收到对方对重新比赛请求的回应"""
        allowed = data.get("allowed", False)
        username = data.get("username")
        
        if allowed:
            # 对方同意重新比赛
            self.add_chat_message("系统", f"对手 {username} 同意了再来一局")
            # 重置游戏状态会在match_found中完成
        else:
            # 对方拒绝重新比赛
            self.add_chat_message("系统", f"对手 {username} 拒绝了再来一局")
            self.rematch_requested = False

    def render_undo_request_dialog(self):
        """渲染悔棋请求对话框"""
        # 创建半透明背景
        overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 128))  # 半透明黑色
        self.screen.blit(overlay, (0, 0))
        
        # 对话框尺寸和位置
        dialog_width = 400
        dialog_height = 300
        dialog_x = (self.width - dialog_width) // 2
        dialog_y = (self.height - dialog_height) // 2
        dialog_rect = pygame.Rect(dialog_x, dialog_y, dialog_width, dialog_height)
        
        # 绘制对话框
        pygame.draw.rect(self.screen, self.white, dialog_rect, 0, 12)
        pygame.draw.rect(self.screen, self.apple_blue, dialog_rect, 3, 12)
        
        # 绘制标题
        title_text = self.title_font.render("悔棋请求", True, self.black)
        title_rect = title_text.get_rect(centerx=dialog_rect.centerx, y=dialog_rect.y + 20)
        self.screen.blit(title_text, title_rect)
        
        # 绘制消息
        message_text = self.info_font.render(f"对手 {self.undo_requester} 请求悔棋", True, self.black)
        message_rect = message_text.get_rect(centerx=dialog_rect.centerx, y=dialog_rect.y + 80)
        self.screen.blit(message_text, message_rect)
        
        # 绘制提示消息
        tip_text = self.info_font.render("您是否同意？", True, self.black)
        tip_rect = tip_text.get_rect(centerx=dialog_rect.centerx, y=dialog_rect.y + 120)
        self.screen.blit(tip_text, tip_rect)
        
        # 绘制同意按钮
        agree_button_rect = pygame.Rect(dialog_x + 50, dialog_rect.y + 180, 120, 50)
        pygame.draw.rect(self.screen, self.apple_blue, agree_button_rect, 0, 8)
        agree_text = self.info_font.render("同意", True, self.white)
        agree_text_rect = agree_text.get_rect(center=agree_button_rect.center)
        self.screen.blit(agree_text, agree_text_rect)
        
        # 绘制拒绝按钮
        disagree_button_rect = pygame.Rect(dialog_x + dialog_width - 170, dialog_rect.y + 180, 120, 50)
        pygame.draw.rect(self.screen, (200, 50, 50), disagree_button_rect, 0, 8)
        disagree_text = self.info_font.render("拒绝", True, self.white)
        disagree_text_rect = disagree_text.get_rect(center=disagree_button_rect.center)
        self.screen.blit(disagree_text, disagree_text_rect)
        
        # 保存按钮区域以便处理点击
        self.undo_agree_button_rect = agree_button_rect
        self.undo_disagree_button_rect = disagree_button_rect

    def render_rematch_request_dialog(self):
        """渲染重新开始游戏请求对话框"""
        # 创建半透明背景
        overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 128))  # 半透明黑色
        self.screen.blit(overlay, (0, 0))
        
        # 对话框尺寸和位置
        dialog_width = 400
        dialog_height = 300
        dialog_x = (self.width - dialog_width) // 2
        dialog_y = (self.height - dialog_height) // 2
        dialog_rect = pygame.Rect(dialog_x, dialog_y, dialog_width, dialog_height)
        
        # 绘制对话框
        pygame.draw.rect(self.screen, self.white, dialog_rect, 0, 12)
        pygame.draw.rect(self.screen, self.apple_blue, dialog_rect, 3, 12)
        
        # 绘制标题
        title_text = self.title_font.render("再来一局请求", True, self.black)
        title_rect = title_text.get_rect(centerx=dialog_rect.centerx, y=dialog_rect.y + 20)
        self.screen.blit(title_text, title_rect)
        
        # 绘制消息
        message_text = self.info_font.render(f"对手请求再来一局", True, self.black)
        message_rect = message_text.get_rect(centerx=dialog_rect.centerx, y=dialog_rect.y + 80)
        self.screen.blit(message_text, message_rect)
        
        # 绘制提示消息
        tip_text = self.info_font.render("您是否同意？", True, self.black)
        tip_rect = tip_text.get_rect(centerx=dialog_rect.centerx, y=dialog_rect.y + 120)
        self.screen.blit(tip_text, tip_rect)
        
        # 绘制同意按钮
        agree_button_rect = pygame.Rect(dialog_x + 50, dialog_rect.y + 180, 120, 50)
        pygame.draw.rect(self.screen, self.apple_blue, agree_button_rect, 0, 8)
        agree_text = self.info_font.render("同意", True, self.white)
        agree_text_rect = agree_text.get_rect(center=agree_button_rect.center)
        self.screen.blit(agree_text, agree_text_rect)
        
        # 绘制拒绝按钮
        disagree_button_rect = pygame.Rect(dialog_x + dialog_width - 170, dialog_rect.y + 180, 120, 50)
        pygame.draw.rect(self.screen, (200, 50, 50), disagree_button_rect, 0, 8)
        disagree_text = self.info_font.render("拒绝", True, self.white)
        disagree_text_rect = disagree_text.get_rect(center=disagree_button_rect.center)
        self.screen.blit(disagree_text, disagree_text_rect)
        
        # 保存按钮区域以便处理点击
        self.rematch_agree_button_rect = agree_button_rect
        self.rematch_disagree_button_rect = disagree_button_rect